package com.atom.common.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.task.Task;

import com.atom.common.CommonConstant;
import com.atom.common.VariablesConstant;
import com.atom.common.util.GlobalConfigReader;
import com.atom.common.util.PreConditionUtil;
import com.atom.common.util.UrlGenerateUtil;
import com.fasterxml.jackson.annotation.JsonFormat;

@Entity
@Table(name="atm_common_ru_task") 
public class RunningTaskDO implements Serializable {

  /** serialVersionUID*/
  private static final long serialVersionUID = 1L;

  /** 主键*/
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)    
  @Column(name="ID")
  private int id;
  
  /** 活动受理人*/
  @Column(name="ASSIGNEE")
  private String assignee;
  
  /** 被代理人*/
  @Column(name="OWNER")
  private String owner;
  
  /** 流程创建人(起草人ID)*/
  @Column(name="PROCESS_CREATOR")
  private String processCreator;
  
  /** 流程创建人部门(起草部门ID)*/
  @Column(name="PROCESS_CREATOR_DEPART")
  private String processCreatorDepart;
  
  /** 前一步骤操作人*/
  @Column(name="PRE_ASSIGNEE")
  private String previousAssignee;
  
  /** 锁定标志*/
  @Column(name="IS_LOCK")
  private boolean isLock;
  
  /** 流程实例名称(任务名称)*/
  @Column(name="PROCESS_INS_NAME")
  private String processInstanceName;
  
  /** 公文编号*/
  @Column(name="PROCESS_NUM")
  private String processNumber;
  
  /** 系统模块*/
  @Column(name="SYSTEM_MODULER")
  private String systemModuler;

  /** 流程定义名称(公文类型ID)*/
  @Column(name="PROCESS_DEF_KEY")
  private String processDefinitionKey;
  
  /** 流程定义名称(DOCTYPENAME)*/
  @Column(name="PROCESS_DEF_NAME")
  private String processDefinitionName;
  
  /** 任务名称(工作步骤)*/
  @Column(name="TASK_NAME")
  private String taskName;
  
  /** 退回标志*/
  @Column(name="IS_REJECT")
  private boolean isReject;
  
  /** 开始时间*/
  @JsonFormat(pattern = CommonConstant.DATETIME_PATTERN)
  @Column(name="CREATE_TIME")
  private Date createTime;

  /** 结束时间*/
  @JsonFormat(pattern = CommonConstant.DATETIME_PATTERN)
  @Column(name="FINISH_TIME")
  private Date finishTime;
  
  /** 详细信息*/
  @Column(name="DETAIL_URL")
  private String detailUrl;
  
  /** 流程图*/
  @Column(name="DIAGRAM_URL")
  private String diagramUrl;

  /** 操作日志*/
  @Column(name="LOG_URL")
  private String logUrl;

  /** 加锁*/
  @Column(name="LOCK_URL")
  private String lockUrl;
  
  /** 优先级*/
  @Column(name="PRIORITY")
  private String priority;  

  /** 主流程实例ID*/
  @Column(name="MAIN_PROC_INS_ID")
  private String mainProcessInstanceId;
  
  /** 流程实例Id*/
  @Column(name="PROCESS_INS_ID")
  private String processInstanceId;
  
  /** 活动定义ID(工作步骤ID)*/
  @Column(name="TASK_DEF_KEY")
  private String taskDefinitionKey;
  
  /** 任务ID(活动实例Id)*/
  @Column(name="TASK_ID")
  private String taskId;
  
  /** 流程版本*/
  @Column(name="PROCESS_VERSION")
  private String processVersion;

  /** 是否最新*/
  @Column(name="IS_LATEST")
  private boolean isLatest;  

  public RunningTaskDO() {
    super();
  }
  
  public static RunningTaskDO getRunningTaskDO(Task task, Map<String, Object> variables, String userId, String ownerId) {
    preCheck(task, variables, userId);
    RunningTaskDO entity = build(task, variables, userId, ownerId);
    return entity;
  }

  public static RunningTaskDO getRunningTaskDO(DelegateTask task, Map<String, Object> variables, String ownerId, String principalId) {
    preCheck(task, variables, ownerId);
    RunningTaskDO entity = build(task, variables, ownerId, principalId);
    return entity;
  }
  
  private static void preCheck(Task task, Map<String, Object> variables, String userId) {
    PreConditionUtil.checkNotNull(task, "task is null");

    PreConditionUtil.checkNotNull(variables, "variables is null");

    PreConditionUtil.checkNotNull(userId, "assignee is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_CREATOR), "processCreator is null");

    //PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_CREATOR_DEPART), "processCreatorDepart is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_INSTANCE_NAME), "taskName is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_NUMBER), "processNumber is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.SYSTEM_MODULER), "systemModuler is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_DEFINITION_KEY), "processDefinitionKey is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_DEFINITION_NAME), "processDefinitionName is null");

    PreConditionUtil.checkNotNull(task.getName(), "taskName is null");

    PreConditionUtil.checkNotNull(task.getCreateTime(), "createTime is null");

    PreConditionUtil.checkNotNull(VariablesConstant.IS_REJECT, "isReject is null");

    PreConditionUtil.checkNotNull(VariablesConstant.PRIORITY, "priority is null");

    PreConditionUtil.checkNotNull(task.getTaskDefinitionKey(), "taskDefinitionKey is null");

    PreConditionUtil.checkNotNull(VariablesConstant.MAIN_PROCESS_INSTANCE_ID, "mainProcessInstanceId : String is null");

    PreConditionUtil.checkNotNull(task.getId(), "taskId : String is null");

    PreConditionUtil.checkNotNull(task.getProcessInstanceId(), "processInstanceId : String is null");
  }

  private static void preCheck(DelegateTask task, Map<String, Object> variables, String userId) {
    PreConditionUtil.checkNotNull(task, "task is null");

    PreConditionUtil.checkNotNull(variables, "variables is null");

    PreConditionUtil.checkNotNull(userId, "assignee is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_CREATOR), "processCreator is null");

    //PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_CREATOR_DEPART), "processCreatorDepart is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_INSTANCE_NAME), "taskName is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_NUMBER), "processNumber is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.SYSTEM_MODULER), "systemModuler is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_DEFINITION_KEY), "processDefinitionKey is null");

    PreConditionUtil.checkNotNull(variables.get(VariablesConstant.PROCESS_DEFINITION_NAME), "processDefinitionName is null");

    PreConditionUtil.checkNotNull(task.getName(), "taskName is null");

    PreConditionUtil.checkNotNull(task.getCreateTime(), "createTime is null");

    PreConditionUtil.checkNotNull(VariablesConstant.IS_REJECT, "isReject is null");

    PreConditionUtil.checkNotNull(VariablesConstant.PRIORITY, "priority is null");

    PreConditionUtil.checkNotNull(task.getTaskDefinitionKey(), "taskDefinitionKey is null");

    PreConditionUtil.checkNotNull(VariablesConstant.MAIN_PROCESS_INSTANCE_ID, "mainProcessInstanceId : String is null");

    PreConditionUtil.checkNotNull(task.getId(), "taskId : String is null");

    PreConditionUtil.checkNotNull(task.getProcessInstanceId(), "processInstanceId : String is null");
  }
  
  private static RunningTaskDO build(Task task, Map<String, Object> variables, String assignee, String owner) {
    RunningTaskDO entity = new RunningTaskDO();    

    entity.setAssignee(assignee);
    
    entity.setOwner(owner);

    entity.setProcessCreator((String) variables.get(VariablesConstant.PROCESS_CREATOR));

    entity.setProcessCreatorDepart((String) variables.get(VariablesConstant.PROCESS_CREATOR_DEPART));

    entity.setPreviousAssignee((String) variables.get(VariablesConstant.PREVIOUS_ASSIGNEE));

    if (GlobalConfigReader.getBooleanValue(CommonConstant.LOCK_AUTOMODE)) {
      entity.setLock((task.getAssignee() == null || task.getAssignee().isEmpty()) ? false : true);
    } else {
      entity.setLock(false);
    }    

    entity.setProcessInstanceName((String) variables.get(VariablesConstant.PROCESS_INSTANCE_NAME));

    entity.setProcessNumber((String) variables.get(VariablesConstant.PROCESS_NUMBER));

    entity.setSystemModuler((String) variables.get(VariablesConstant.SYSTEM_MODULER));

    entity.setProcessDefinitionKey((String) variables.get(VariablesConstant.PROCESS_DEFINITION_KEY));

    entity.setProcessDefinitionName((String) variables.get(VariablesConstant.PROCESS_DEFINITION_NAME));

    entity.setTaskName(task.getName());

    entity.setCreateTime(task.getCreateTime());

    entity.setReject((Boolean) variables.get(VariablesConstant.IS_REJECT) == Boolean.TRUE ? true : false);    

    entity.setPriority((String) variables.get(VariablesConstant.PRIORITY));

    entity.setFinishTime(task.getDueDate());

    entity.setMainProcessInstanceId((String) variables.get(VariablesConstant.MAIN_PROCESS_INSTANCE_ID));

    entity.setProcessInstanceId(task.getProcessInstanceId());

    entity.setTaskDefinitionKey(task.getTaskDefinitionKey());

    entity.setTaskId(task.getId());

    entity.setDetailUrl(UrlGenerateUtil.getDetailUrl(task.getTaskDefinitionKey(), 
        (String) variables.get(VariablesConstant.PROCESS_DEFINITION_KEY), 
        task.getId()));

    entity.setDiagramUrl(UrlGenerateUtil.getDiagramUrl(task.getTaskDefinitionKey(), 
        (String) variables.get(VariablesConstant.PROCESS_DEFINITION_KEY), 
        (String) variables.get(VariablesConstant.MAIN_PROCESS_INSTANCE_ID)));

    entity.setLogUrl(UrlGenerateUtil.getLogUrl((String) variables.get(VariablesConstant.MAIN_PROCESS_INSTANCE_ID),
        (String) variables.get(VariablesConstant.PROCESS_DEFINITION_KEY)));

    entity.setLockUrl(UrlGenerateUtil.getLockUrl(task.getId(), owner));

    return entity;
  }

  private static RunningTaskDO build(DelegateTask task, Map<String, Object> variables, String assignee, String owner) {
    RunningTaskDO entity = new RunningTaskDO();    

    entity.setAssignee(assignee);
    
    entity.setOwner(owner);

    entity.setProcessCreator((String) variables.get(VariablesConstant.PROCESS_CREATOR));

    entity.setProcessCreatorDepart((String) variables.get(VariablesConstant.PROCESS_CREATOR_DEPART));

    entity.setPreviousAssignee((String) variables.get(VariablesConstant.PREVIOUS_ASSIGNEE));

    if (GlobalConfigReader.getBooleanValue(CommonConstant.LOCK_AUTOMODE)) {
      entity.setLock((task.getAssignee() == null || task.getAssignee().isEmpty()) ? false : true);
    } else {
      entity.setLock(false);
    }    

    entity.setProcessInstanceName((String) variables.get(VariablesConstant.PROCESS_INSTANCE_NAME));

    entity.setProcessNumber((String) variables.get(VariablesConstant.PROCESS_NUMBER));

    entity.setSystemModuler((String) variables.get(VariablesConstant.SYSTEM_MODULER));

    entity.setProcessDefinitionKey((String) variables.get(VariablesConstant.PROCESS_DEFINITION_KEY));

    entity.setProcessDefinitionName((String) variables.get(VariablesConstant.PROCESS_DEFINITION_NAME));

    entity.setTaskName(task.getName());

    entity.setCreateTime(task.getCreateTime());

    entity.setReject((Boolean) variables.get(VariablesConstant.IS_REJECT) == Boolean.TRUE ? true : false);    

    entity.setPriority((String) variables.get(VariablesConstant.PRIORITY));

    entity.setFinishTime(task.getDueDate());

    entity.setMainProcessInstanceId((String) variables.get(VariablesConstant.MAIN_PROCESS_INSTANCE_ID));

    entity.setProcessInstanceId(task.getProcessInstanceId());

    entity.setTaskDefinitionKey(task.getTaskDefinitionKey());

    entity.setTaskId(task.getId());

    entity.setDetailUrl(UrlGenerateUtil.getDetailUrl(task.getTaskDefinitionKey(), 
        (String) variables.get(VariablesConstant.PROCESS_DEFINITION_KEY), 
        task.getId()));

    entity.setDiagramUrl(UrlGenerateUtil.getDiagramUrl(task.getTaskDefinitionKey(), 
        (String) variables.get(VariablesConstant.PROCESS_DEFINITION_KEY), 
        (String) variables.get(VariablesConstant.MAIN_PROCESS_INSTANCE_ID)));

    entity.setLogUrl(UrlGenerateUtil.getLogUrl((String) variables.get(VariablesConstant.MAIN_PROCESS_INSTANCE_ID),
        (String) variables.get(VariablesConstant.PROCESS_DEFINITION_KEY)));

    entity.setLockUrl(UrlGenerateUtil.getLockUrl(task.getId(), owner));

    return entity;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getAssignee() {
    return assignee;
  }

  public void setAssignee(String assignee) {
    this.assignee = assignee;
  }

  public String getOwner() {
    return owner;
  }

  public void setOwner(String owner) {
    this.owner = owner;
  }

  public String getProcessCreator() {
    return processCreator;
  }

  public void setProcessCreator(String processCreator) {
    this.processCreator = processCreator;
  }

  public String getProcessCreatorDepart() {
    return processCreatorDepart;
  }

  public void setProcessCreatorDepart(String processCreatorDepart) {
    this.processCreatorDepart = processCreatorDepart;
  }

  public String getPreviousAssignee() {
    return previousAssignee;
  }

  public void setPreviousAssignee(String previousAssignee) {
    this.previousAssignee = previousAssignee;
  }

  public String getProcessInstanceName() {
    return processInstanceName;
  }

  public void setProcessInstanceName(String processInstanceName) {
    this.processInstanceName = processInstanceName;
  }

  public String getProcessNumber() {
    return processNumber;
  }

  public void setProcessNumber(String processNumber) {
    this.processNumber = processNumber;
  }

  public String getSystemModuler() {
    return systemModuler;
  }

  public void setSystemModuler(String systemModuler) {
    this.systemModuler = systemModuler;
  }

  public String getProcessDefinitionKey() {
    return processDefinitionKey;
  }

  public void setProcessDefinitionKey(String processDefinitionKey) {
    this.processDefinitionKey = processDefinitionKey;
  }

  public String getTaskName() {
    return taskName;
  }

  public void setTaskName(String taskName) {
    this.taskName = taskName;
  }

  public boolean isReject() {
    return isReject;
  }

  public void setReject(boolean isReject) {
    this.isReject = isReject;
  }

  public Date getCreateTime() {
    return createTime;
  }

  public void setCreateTime(Date createTime) {
    this.createTime = createTime;
  }

  public Date getFinishTime() {
    return finishTime;
  }

  public void setFinishTime(Date finishTime) {
    this.finishTime = finishTime;
  }

  public String getDetailUrl() {
    return detailUrl;
  }

  public void setDetailUrl(String detailUrl) {
    this.detailUrl = detailUrl;
  }

  public String getPriority() {
    return priority;
  }

  public void setPriority(String priority) {
    this.priority = priority;
  }

  public String getDiagramUrl() {
    return diagramUrl;
  }

  public void setDiagramUrl(String diagramUrl) {
    this.diagramUrl = diagramUrl;
  }

  public String getLogUrl() {
    return logUrl;
  }

  public void setLogUrl(String logUrl) {
    this.logUrl = logUrl;
  }

  public String getMainProcessInstanceId() {
    return mainProcessInstanceId;
  }

  public void setMainProcessInstanceId(String mainProcessInstanceId) {
    this.mainProcessInstanceId = mainProcessInstanceId;
  }

  public String getProcessInstanceId() {
    return processInstanceId;
  }

  public void setProcessInstanceId(String processInstanceId) {
    this.processInstanceId = processInstanceId;
  }

  public String getTaskDefinitionKey() {
    return taskDefinitionKey;
  }

  public void setTaskDefinitionKey(String taskDefinitionKey) {
    this.taskDefinitionKey = taskDefinitionKey;
  }

  public String getTaskId() {
    return taskId;
  }

  public void setTaskId(String taskId) {
    this.taskId = taskId;
  }

  public String getProcessVersion() {
    return processVersion;
  }

  public void setProcessVersion(String processVersion) {
    this.processVersion = processVersion;
  }

  public boolean isLatest() {
    return isLatest;
  }

  public void setLatest(boolean isLatest) {
    this.isLatest = isLatest;
  }

  public String getProcessDefinitionName() {
    return processDefinitionName;
  }

  public void setProcessDefinitionName(String processDefinitionName) {
    this.processDefinitionName = processDefinitionName;
  }

  public boolean isLock() {
    return isLock;
  }

  public void setLock(boolean isLock) {
    this.isLock = isLock;
  }

  public String getLockUrl() {
    return lockUrl;
  }

  public void setLockUrl(String lockUrl) {
    this.lockUrl = lockUrl;
  }
  
  

}
